package http

import (
	"encoding/json"
	"fmt"
	"gitee.com/legend9999/publisher/modle"
	"gitee.com/legend9999/publisher/service"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"strconv"
	"time"
)

var bookService service.BookService
var bookStatusService service.BookStatusService
var userService service.UserService

type BookHandler int

func (b *BookHandler) bookList(c *gin.Context) {
	page := NewPageFromR(c.Request)
	book := new(modle.Book)
	if err := c.ShouldBind(book); err != nil {
		c.JSON(http.StatusForbidden, "res")
		c.Abort()
		return
	}
	err := bookService.Page(page.Page, book)
	if err != nil {
		log.Printf("query book page err:%s", err)
	}
	stage := book.Stage
	if stage == 0 {
		stage = 1
	}
	c.HTML(http.StatusOK, fmt.Sprintf("book/list_%d.html", stage), newHTMLData(c, page))
}
func (b *BookHandler) all(c *gin.Context) {
	list, err := bookService.All()
	if err != nil {
		log.Printf("query book page err:%s", err)
		return
	}
	marshal, _ := json.Marshal(list)
	c.JSON(http.StatusOK, string(marshal))
}

func (b *BookHandler) create(c *gin.Context) {
	if c.Request.Method == http.MethodGet {
		c.HTML(http.StatusOK, "book/create.html", newHTMLData(c, nil))
		return
	}
	if c.Request.Method == http.MethodPost {
		book := new(modle.Book)
		if err := c.ShouldBind(book); err != nil {
			c.JSON(http.StatusForbidden, "res")
			c.Abort()
			return
		}
		user := GetSessionUser(c)
		err := bookService.Create(user, book)
		if err != nil {
			log.Printf("bookService.Create err:%s", err)
			c.JSON(http.StatusForbidden, err)
			return
		}
		c.JSON(http.StatusOK, "ok")
		return
	}
}

func (b *BookHandler) finishStatus(c *gin.Context) {
	bookIDStr := c.Query("id")
	statusStr := c.Query("status")

	bookID, _ := strconv.ParseInt(bookIDStr, 10, 64)
	currentStatus, _ := strconv.Atoi(statusStr)
	bookStatus, _ := bookStatusService.Query(bookID, modle.Status(currentStatus))

	now := time.Now()
	bookStatus.FinishTime = &now

	bookStatusService.Save(bookStatus)

	nextStatus := b.nextStatusBackend(modle.Status(currentStatus))
	nextBookStage := modle.BookStage(nextStatus)
	book, _ := bookService.Query(bookID)
	book.Stage = nextBookStage
	book.Status = nextStatus
	err := bookService.Update(book)
	if err != nil {
		log.Printf("bookService.Create err:%s", err)
		c.JSON(http.StatusForbidden, err)
		return
	}
	c.JSON(http.StatusOK, "ok")
	return
}

func (b *BookHandler) nextStatusBackend(status modle.Status) (nextStage modle.Status) {
	var nexStatus modle.Status
	if status == modle.S1_7 {
		nexStatus = modle.S2_1
	} else if status == modle.S2_3 {
		nexStatus = modle.S3_1
	} else if status == modle.S3_3 {
		nexStatus = modle.S4_1
	} else {
		nexStatus = status + 1
	}
	return nexStatus
}

func (b *BookHandler) startStatus(c *gin.Context) {
	bookIDStr := c.Query("id")
	statusStr := c.Query("status")

	bookID, _ := strconv.ParseInt(bookIDStr, 10, 64)
	status, _ := strconv.Atoi(statusStr)

	bookStatus, _ := bookStatusService.Query(bookID, modle.Status(status))
	now := time.Now()
	bookStatus.StartTime = &now

	err := bookStatusService.Save(bookStatus)

	if err != nil {
		log.Printf("bookService.Create err:%s", err)
		c.JSON(http.StatusForbidden, err)
		return
	}
	c.JSON(http.StatusOK, "ok")
	return
}

func (b *BookHandler) detail(c *gin.Context) {
	bookIDStr := c.Query("id")
	bookID, _ := strconv.ParseInt(bookIDStr, 10, 64)
	book, _ := bookService.Query(bookID)

	c.HTML(http.StatusOK, "book/detail.html", newHTMLData(c, book))
	return
}

func (b *BookHandler) edit(c *gin.Context) {
	if c.Request.Method == http.MethodGet {
		bookIDStr := c.Query("id")
		bookID, _ := strconv.ParseInt(bookIDStr, 10, 64)
		book, _ := bookService.Query(bookID)
		c.HTML(http.StatusOK, "book/update.html", newHTMLData(c, book))
		return
	}
	book := new(modle.Book)
	if err := c.ShouldBind(book); err != nil {
		c.JSON(http.StatusForbidden, "res")
		c.Abort()
		return
	}
	err := bookService.Update(book)
	if err != nil {
		log.Printf("bookService.Update err:%s", err)
		c.JSON(http.StatusForbidden, err)
		return
	}
	c.JSON(http.StatusOK, "ok")
	return
}

func (b *BookHandler) del(c *gin.Context) {
	bookIDStr := c.Query("id")
	bookID, _ := strconv.ParseInt(bookIDStr, 10, 64)
	err := bookService.Delete(bookID)
	if err != nil {
		log.Printf("bookService.Create err:%s", err)
		c.JSON(http.StatusForbidden, err)
		return
	}
	c.JSON(http.StatusOK, "ok")
	return
}
